package com.exposit.smarthouse.system.impl;

import com.exposit.smarthouse.system.*;
import com.exposit.smarthouse.environment.*;
import com.exposit.smarthouse.environment.impl.*;
import com.exposit.smarthouse.model.*;
import com.exposit.smarthouse.sensor.impl.*;
import com.exposit.smarthouse.state.*;
import com.exposit.smarthouse.state.impl.*;
import com.exposit.smarthouse.utils.*;
import org.apache.log4j.*;

import java.util.concurrent.*;

public class SmokeControlSystemImpl implements SmokeControlSystem
{
    private static final Logger LOG = Logger.getLogger("SmokeControlSystem");

    private SmokeEnvironment smokeEnvironment = new SmokeEnvironmentImpl();

    private ConcurrentLinkedQueue<ISensor> iSensors = new ConcurrentLinkedQueue<ISensor>();

    private ConcurrentHashMap<String, Double> controlParams = new ConcurrentHashMap<String, Double>();

    public SmokeControlSystemImpl()
    {
        smokeEnvironment.addState(new SmokeStateImpl(StartEnvironment.getSmoke()));

        iSensors.add(new SmokeSensorImpl());

        controlParams.put(SmokeState.TYPE + "MIN", 0.5);
    }

    @Override
    public void setEnvironment(SmokeEnvironment environment)
    {
        this.smokeEnvironment = environment;
    }

    @Override
    public SmokeEnvironment getEnvironment()
    {
        return smokeEnvironment;
    }

    @Override
    public void addSensor(ISensor sensor)
    {
        this.iSensors.add(sensor);
    }

    @Override
    public ConcurrentLinkedQueue<ISensor> getSensors()
    {
        return iSensors;
    }


    @Override
    public void start() {
        try
        {
            LOG.info("GET SENSORS STATE");
            getSensorState();
            Thread.sleep(3000);

            LOG.info("CHANGE STATES");
            changeState();

            Thread.sleep(3000);
            LOG.info("GET SENSORS STATE");
            getSensorState();

        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

    @SuppressWarnings("unchecked")
    private void getSensorState() {
        for (ISensor iSensor : iSensors) {
            Double min = controlParams.get(iSensor.getType() + "MIN");

            iSensor.setState(smokeEnvironment.getStates().get(iSensor.getType()));
            LOG.info("SENSOR BY " + iSensor.getType() + " TYPE HAVE VALUE " + iSensor.getState().getValue());

            if(iSensor.getValue() > min) {
                LOG.warn("NOTIFICATION CUSTOMER AND FIRE HOUSE");
            }
        }
    }


    private void changeState() {
        ConcurrentMap<String, IState> iStates = smokeEnvironment.getStates();

        for (String identifier : smokeEnvironment.getStates().keySet()) {
            IState iState = iStates.get(identifier);
            LOG.info("STATE BY " + iState.getType() + " TYPE HAVE VALUE BEFORE UPDATE " + iState.getValue());

            iState.setValue(StartEnvironment.randomValue(iState));

            LOG.info("STATE BY " + iState.getType() + " TYPE HAVE VALUE AFTER UPDATE " + iState.getValue());
            iStates.replace(identifier, iState);

        }
    }
}